package ServiceImp;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import DAO.CartDAO;
import DAO.CartDetailDAO;
import DAO.CategoryDAO;
import DAO.CustomerDAO;
import DAO.CustomerTypeDAO;
import DAO.ProductDAO;
import DAO.ProductDetailDAO;
import DAO.TypeDAO;
import DAO.TypeDetailDAO;
import DAO.UserDAO;
import DAO.UserRoleDAO;
import ModelBean.NodeCategory;
import ModelBean.RegisterBean;
import ModelBean.Tag;
import POJO.Cart;
import POJO.CartDetail;
import POJO.Category;
import POJO.Customer;
import POJO.Product;
import POJO.ProductDetail;
import POJO.Type;
import POJO.TypeDetail;
import POJO.User;
import POJO.UserRole;
import Service.HomeService;

@Service("serviceHome")
@Transactional
public class HomeServiceImp implements HomeService {

	@Autowired
	CategoryDAO categoryDao;

	@Autowired
	ProductDetailDAO productDetailDao;

	@Autowired
	TypeDAO typeDao;
	
	@Autowired
	TypeDetailDAO typeDetailDao;

	@Autowired
	UserDAO userDao;
	
	@Autowired
	CustomerDAO customerDao;
	
	@Autowired
	CustomerTypeDAO customerTypeDao;
	
	@Autowired
	UserRoleDAO userRoleDao;
	
	@Autowired
	CartDAO cartDao;
	
	@Autowired
	CartDetailDAO cartDetailDao;
	
	@Autowired
	ProductDAO productDao;
	
	public NodeCategory createTreeMenu() {
		NodeCategory root = new NodeCategory();

		int nLevel = categoryDao.getMaxLevel() + 1;
		List<Category> current = categoryDao.getCategories(0);

		for (Category c : current) {
			root.addChild(c);
		}

		List<NodeCategory> last = new ArrayList<NodeCategory>();
		last.add(root);

		for (int i = 1; i < nLevel; i++) {
			current = categoryDao.getCategories(i);

			for (NodeCategory node : last) {
				for (Category cat : current) {
					for (NodeCategory n : node.childs)
						if (n.value.getCategoryId() == cat.getParentId()) {
							n.addChild(cat);
						}
				}
			}

			List<NodeCategory> tmp = new ArrayList<NodeCategory>();
			for (NodeCategory cc : last) {
				for (NodeCategory ccc : cc.childs) {
					tmp.add(ccc);
				}
			}

			last.clear();
			last = tmp;
		}

		return root;
	}

	public List<ProductDetail> getProductDiscount(int count) {
		return productDetailDao.getProductDiscount(count);
	}

	public ProductDetail getProductById(int id) {
		return productDetailDao.get(id);
	}

	public Long getCountInStore(int id) {
		return productDetailDao.getCountInStore(id);
	}

	public List<Type> getTypes() {
		return typeDao.getAll();
	}

	public List<ProductDetail> getProductNew(int count) {
		return productDetailDao.getProductNew(count);
	}

	public Category getCategoryById(int id) {
		return categoryDao.get(id);
	}

	public List<Category> createNavi(int id, int type) {
		List<Category> navi = new ArrayList<Category>();
		int temp = id;
		if (type != 1) {
			int i = 0;
			for (Category cate : productDetailDao.get(id).getProduct()
					.getCategories()) {
				if (i < cate.getPriority()) {
					i = cate.getPriority();
					temp = cate.getCategoryId();
				}
			}
		}

		int level = categoryDao.get(temp).getPriority();
		int parent = categoryDao.get(temp).getParentId();
		navi.add(categoryDao.get(temp));
		while (level != 0) {
			level = categoryDao.get(parent).getPriority();
			navi.add(categoryDao.get(parent));
			parent = categoryDao.get(parent).getParentId();
		}

		Collections.reverse(navi);
		return navi;
	}

	public int createUser(RegisterBean register) {
		userDao.create(new User(register.getUserName(), register.getPassWord()));
		User current = userDao.findUserByUserName(register.getUserName());
		userRoleDao.create(new UserRole(current, "ROLE_USER"));
		int customerId =  customerDao.create(
				new Customer(register.getFirstName(), register.getLastName(), register.getAddress(), register.getPhone(),
						register.getGender(), register.getEmail(), customerTypeDao.get(2), current));
		cartDao.create(new Cart(new Date(), 0, customerDao.get(customerId)));
		return customerId;
	}

	public List<TypeDetail> getTypeDetails() {
		return typeDetailDao.getAll();
	}
	public Cart getCart() {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
	    String name = auth.getName(); //get logged in username
	    //System.out.println("username = " +name);
	    User user = userDao.findUserByUserName(name);
	    if (user != null && this.getUserRole().equals("User")){
		    Customer cus = user.getCustomer();
		    if (cus != null){
		    	//System.out.println("customerId = " +cus.getCustomerId());
		    }
			return cus.getCarts().iterator().next();
	    }

	    return null;
	}

	public String getUserRole() {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
	    String name = auth.getName(); //get logged in username
	    //System.out.println("username = " +name);
	    User user = userDao.findUserByUserName(name);
	    if (user != null){
	    	for (UserRole userrole : user.getUserRoles()){
	    		if (userrole.getRole().equals("ROLE_ADMIN")){
	    			return "Admin";
	    		}
	    		else{
	    			return "User";
	    		}
	    	}
	    }
		return "";
	}

	public void storeCart(Cart cart) {
		cartDao.update(cart);
	}

	public void storeCartDetail(CartDetail cartdetail) {
		cartDetailDao.create(cartdetail);
	}

	public void deleteCartDetail(int id) {
		cartDetailDao.delete(cartDetailDao.get(id));
	}

	public List<Tag> getAllTag() {
		List<Product> products = productDao.getAll();
		List<Tag> tags = new ArrayList<Tag>();
		List<String> tagsStr = new ArrayList<String>();
		String splitBy = ",";
		String tag;
		String[] alltag;
		for (Product product : products){
			tag = product.getTag();
			alltag = tag.split(splitBy);
			for (String str : alltag){
				if (!tagsStr.contains(str)){
					System.out.println("tag "+str);
					tagsStr.add(str);
				}
			}
		}
		for (int i = 0, n = tagsStr.size(); i < n; i++){
			tags.add(new Tag(i, tagsStr.get(i)));
		}
		return tags;
	}

	public List<Product> getAllProductDetailByTag(String searchString) {
		List<Product> p= productDao.getAllProductByTag(searchString);
		return p;
	}
	
}
